package com.rankeiot.platform.service;

import com.rankeiot.core.EasyCorePlugin;
import com.rankeiot.core.MenuManager;
import com.rankeiot.core.data.MenuItem;
import com.rankeiot.core.sqltoy.TableUtil;
import com.rankeiot.core.util.CollectionUtil;
import com.rankeiot.core.util.StringUtil;
import com.rankeiot.platform.domain.Menu;
import io.swagger.v3.oas.annotations.servers.Server;
import lombok.RequiredArgsConstructor;
import org.sagacity.sqltoy.dao.LightDao;
import org.sagacity.sqltoy.dao.SqlToyLazyDao;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class MenuService {
    final SqlToyLazyDao dao;
    private  Map<String, Map<String, MenuItem>> systemMenus = null;
    @EventListener
    public void onContextRefreshedEvent(ContextRefreshedEvent event) {
        if(!EasyCorePlugin.hasDataSource){
            return;
        }
        TableUtil.hasTable(dao.getDataSource(),Menu.TABLE,(conn,name)->{
            if(name==null){
                TableUtil.createTable(dao,Menu.class);
            }
        });
        systemMenus = new HashMap<>(MenuManager.getGroupMenus());
        syncMenu();
    }

    /**
     * 同步菜单
     */
    public void syncMenu() {
        if(!EasyCorePlugin.hasDataSource){
            return;
        }
        List<Menu> toAdd = new ArrayList<>();
        List<Menu> toUpdate = new ArrayList<>();
        List<Menu> toDelete = new ArrayList<>();

        //同步菜单
        Map<String, Map<String, MenuItem>> ms = systemMenus;

        //加载数据库菜单
        List<Menu> menuList = dao.findBySql("select * from t_menu", new Menu());

        //检测需要删除的项
        Map<String, Menu> menuMap = new HashMap<>();
        for (Menu menu : menuList) {
            menuMap.put(menu.getMenuGroup() + menu.getId(), menu);
            if (menu.getSystem()) {
                Map<String, MenuItem> g = ms.get(menu.getMenuGroup());
                if (g != null) {
                    if (g.get(menu.getId()) != null) {
                        continue;
                    }
                }
                toDelete.add(menu);
            }
        }

        for (Map.Entry<String, Map<String, MenuItem>> group : ms.entrySet()) {
            String groupName = group.getKey();
            Map<String, MenuItem> menus = group.getValue();
            for (MenuItem it : menus.values()) {
                Menu m = new Menu();

                m.fillItem(it);
                m.setMenuGroup(groupName);

                Menu old = menuMap.get(groupName + it.getKey());
                if (old == null) {
                    m.setEnable(it.isEnable());
                    m.setSort(it.getOrder());
                    toAdd.add(m);
                } else {
                    m.setIcon(old.getIcon());
                    m.setTitle(old.getTitle());
                    m.setEnable(old.getEnable());
                    m.setSort(old.getSort());
                    m.setPath(old.getPath());
                    toUpdate.add(m);
                }
            }
        }
        if (toAdd.size() > 0) {
            dao.saveAll(toAdd);
        }
        if (toUpdate.size() > 0) {
            dao.updateAll(toUpdate);
        }
        if (toDelete.size() > 0) {
            dao.deleteAll(toDelete);
        }

        reloadMenu();
    }

    /**
     * 重新从数据库加载菜单
     */
    public synchronized void reloadMenu() {
        //清除菜单缓存
        MenuManager.getGroupMenus().clear();
        //加载数据库菜单
        List<Menu> menuList = dao.findBySql("select * from t_menu", new Menu());
        //更新菜单
        for (Menu menu : menuList) {
            String group = menu.getMenuGroup();
            MenuItem item=menu.createItem();
            MenuManager.addMenu(group, item);
        }

    }
}
